package com.simple.gateway.center.basedata.repository;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.simple.gateway.center.basedata.common.PageUtil;
import com.simple.gateway.center.basedata.common.SimpleGatewayConstants;
import com.simple.gateway.center.basedata.mapper.ApplicationInterfaceMapper;
import com.simple.gateway.center.basedata.mapper.ApplicationInterfaceMethodMapper;
import com.simple.gateway.center.basedata.mapper.ApplicationSystemMapper;
import com.simple.gateway.center.basedata.po.ApplicationInterface;
import com.simple.gateway.center.basedata.po.ApplicationInterfaceMethod;
import com.simple.gateway.center.basedata.po.ApplicationSystem;
import com.simple.gateway.center.basedata.po.GatewayDistribution;
import com.simple.gateway.center.domian.application.bo.ApplicationInterfaceBO;
import com.simple.gateway.center.domian.application.bo.ApplicationInterfaceMethodBO;
import com.simple.gateway.center.domian.application.bo.ApplicationSystemBO;
import com.simple.gateway.center.domian.application.repository.IApplicationManageRepository;
import com.simple.gateway.center.domian.manage.bo.GatewayDistributionBO;
import com.simple.gateway.center.web.param.ApplicationCompositeParam;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 项目: simple-gateway-core
 * <p>
 * 功能描述:
 *
 * @author: WuChengXing
 * @create: 2023-08-07 17:22
 **/
@Component
public class ApplicationManageRepository implements IApplicationManageRepository {

    @Resource
    private ApplicationSystemMapper applicationSystemMapper;
    @Resource
    private ApplicationInterfaceMapper applicationInterfaceMapper;
    @Resource
    private ApplicationInterfaceMethodMapper applicationInterfaceMethodMapper;

    @Override
    public void registerApplication(ApplicationSystemBO applicationSystemBO) {
        applicationSystemMapper.insertApplicationSystem(ApplicationSystemBO.bo2Do(applicationSystemBO));
    }

    @Override
    public void registerApplicationInterface(ApplicationInterfaceBO applicationInterfaceBO) {
        applicationInterfaceMapper.insertApplicationInterface(ApplicationInterfaceBO.bo2Do(applicationInterfaceBO));
    }

    @Override
    public void registerApplicationInterfaceMethod(ApplicationInterfaceMethodBO applicationInterfaceMethodBO) {
        applicationInterfaceMethodMapper.insertApplicationInterfaceMethod(ApplicationInterfaceMethodBO.bo2Do(applicationInterfaceMethodBO));
    }


    @Override
    public List<ApplicationSystemBO> queryApplicationSystemList(List<String> systemIdList) {
        LambdaQueryWrapper<ApplicationSystem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApplicationSystem::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        queryWrapper.in(ApplicationSystem::getSystemId, systemIdList);
        List<ApplicationSystem> applicationSystemList = applicationSystemMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(applicationSystemList)) {
            return Collections.emptyList();
        }
        return applicationSystemList.stream().map(ApplicationSystemBO::do2Bo).collect(Collectors.toList());
    }

    @Override
    public List<ApplicationInterfaceBO> queryApplicationInterfaceList(String systemId) {
        LambdaQueryWrapper<ApplicationInterface> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApplicationInterface::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        queryWrapper.in(ApplicationInterface::getSystemId, systemId);
        List<ApplicationInterface> applicationInterfaces = applicationInterfaceMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(applicationInterfaces)) {
            return Collections.emptyList();
        }
        return applicationInterfaces.stream().map(ApplicationInterfaceBO::do2Bo).collect(Collectors.toList());
    }

    @Override
    public List<ApplicationInterfaceMethodBO> queryApplicationInterfaceMethodList(String systemId, String interfaceId) {
        LambdaQueryWrapper<ApplicationInterfaceMethod> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApplicationInterfaceMethod::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        queryWrapper.in(Objects.nonNull(systemId), ApplicationInterfaceMethod::getSystemId, systemId);
        queryWrapper.in(Objects.nonNull(interfaceId), ApplicationInterfaceMethod::getInterfaceId, interfaceId);
        List<ApplicationInterfaceMethod> applicationInterfaceMethods = applicationInterfaceMethodMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(applicationInterfaceMethods)) {
            return Collections.emptyList();
        }
        return applicationInterfaceMethods.stream().map(ApplicationInterfaceMethodBO::do2Bo).collect(Collectors.toList());
    }

    @Override
    public List<ApplicationInterfaceMethodBO> queryApplicationInterfaceMethodList(String systemId, String interfaceId, List<Long> ids) {
        LambdaQueryWrapper<ApplicationInterfaceMethod> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApplicationInterfaceMethod::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        queryWrapper.in(Objects.nonNull(systemId), ApplicationInterfaceMethod::getSystemId, systemId);
        queryWrapper.in(Objects.nonNull(interfaceId), ApplicationInterfaceMethod::getInterfaceId, interfaceId);
        queryWrapper.in(Objects.nonNull(ids), ApplicationInterfaceMethod::getId, ids);
        List<ApplicationInterfaceMethod> applicationInterfaceMethods = applicationInterfaceMethodMapper.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(applicationInterfaceMethods)) {
            return Collections.emptyList();
        }
        return applicationInterfaceMethods.stream().map(ApplicationInterfaceMethodBO::do2Bo).collect(Collectors.toList());
    }

    @Override
    public Page<ApplicationSystemBO> pageApplicationSystem(ApplicationCompositeParam param) {
        Page<ApplicationSystem> buildPage = new Page<>(param.getPageNum(), param.getPageSize());
        LambdaQueryWrapper<ApplicationSystem> queryWrapper = new LambdaQueryWrapper<>();
        buildSystemSearch(queryWrapper, param);
        queryWrapper.eq(ApplicationSystem::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        Page<ApplicationSystem> gatewayDistributionPage = applicationSystemMapper.selectPage(buildPage, queryWrapper);
        List<ApplicationSystemBO> collect = gatewayDistributionPage.getRecords().stream().map(ApplicationSystemBO::do2Bo).collect(Collectors.toList());
        return PageUtil.convertPage(gatewayDistributionPage, collect);
    }

    private void buildSystemSearch(LambdaQueryWrapper<ApplicationSystem> queryWrapper,
                                   ApplicationCompositeParam param) {
        if (StrUtil.isNotBlank(param.getSystemId())) {
            queryWrapper.like(ApplicationSystem::getSystemId, param.getSystemId());
        }
        if (StrUtil.isNotBlank(param.getSystemName())) {
            queryWrapper.like(ApplicationSystem::getSystemName, param.getSystemName());
        }
        if (StrUtil.isNotBlank(param.getSystemType())) {
            queryWrapper.eq(ApplicationSystem::getSystemType, param.getSystemType());
        }
    }

    @Override
    public Page<ApplicationInterfaceBO> pageApplicationInterface(ApplicationCompositeParam param) {
        Page<ApplicationInterface> buildPage = new Page<>(param.getPageNum(), param.getPageSize());
        LambdaQueryWrapper<ApplicationInterface> queryWrapper = new LambdaQueryWrapper<>();
        buildInterfaceSearch(queryWrapper, param);
        queryWrapper.eq(ApplicationInterface::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        Page<ApplicationInterface> gatewayDistributionPage = applicationInterfaceMapper.selectPage(buildPage, queryWrapper);
        List<ApplicationInterfaceBO> collect = gatewayDistributionPage.getRecords().stream().map(ApplicationInterfaceBO::do2Bo).collect(Collectors.toList());
        return PageUtil.convertPage(gatewayDistributionPage, collect);
    }

    private void buildInterfaceSearch(LambdaQueryWrapper<ApplicationInterface> queryWrapper,
                                      ApplicationCompositeParam param) {
        if (StrUtil.isNotBlank(param.getInterfaceId())) {
            queryWrapper.eq(ApplicationInterface::getInterfaceId, param.getInterfaceId());
        }
        if (StrUtil.isNotBlank(param.getInterfaceName())) {
            queryWrapper.like(ApplicationInterface::getInterfaceName, param.getInterfaceName());
        }
        if (StrUtil.isNotBlank(param.getSystemId())) {
            queryWrapper.like(ApplicationInterface::getSystemId, param.getSystemId());
        }
    }

    @Override
    public Page<ApplicationInterfaceMethodBO> pageApplicationMethod(ApplicationCompositeParam param) {
        Page<ApplicationInterfaceMethod> buildPage = new Page<>(param.getPageNum(), param.getPageSize());
        LambdaQueryWrapper<ApplicationInterfaceMethod> queryWrapper = new LambdaQueryWrapper<>();
        buildMethodSearch(queryWrapper, param);
        queryWrapper.eq(ApplicationInterfaceMethod::getIsDeleted, SimpleGatewayConstants.NOT_DELETED);
        Page<ApplicationInterfaceMethod> gatewayDistributionPage = applicationInterfaceMethodMapper.selectPage(buildPage, queryWrapper);
        List<ApplicationInterfaceMethodBO> collect = gatewayDistributionPage.getRecords().stream().map(ApplicationInterfaceMethodBO::do2Bo).collect(Collectors.toList());
        return PageUtil.convertPage(gatewayDistributionPage, collect);
    }

    private void buildMethodSearch(LambdaQueryWrapper<ApplicationInterfaceMethod> queryWrapper,
                                   ApplicationCompositeParam param) {
        if (StrUtil.isNotBlank(param.getSystemId())) {
            queryWrapper.like(ApplicationInterfaceMethod::getSystemId, param.getSystemId());
        }
        if (StrUtil.isNotBlank(param.getMethodId())) {
            queryWrapper.eq(ApplicationInterfaceMethod::getMethodId, param.getMethodId());
        }
        if (StrUtil.isNotBlank(param.getInterfaceId())) {
            queryWrapper.eq(ApplicationInterfaceMethod::getInterfaceId, param.getInterfaceId());
        }
        if (StrUtil.isNotBlank(param.getHttpCommandType())) {
            queryWrapper.eq(ApplicationInterfaceMethod::getHttpCommandType, param.getHttpCommandType());
        }
        if (Objects.nonNull(param.getAuth())) {
            queryWrapper.eq(ApplicationInterfaceMethod::getAuth, param.getAuth());
        }
    }
}
